package fr.umlv.users;

import java.awt.Cursor;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.logging.Level;

import javax.swing.AbstractListModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;

import kiyut.ekspos.BrowserWindow;

import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
import org.jdesktop.swingx.JXErrorPane;
import org.jdesktop.swingx.error.ErrorInfo;

import fr.umlv.authentication.SessionHandler;
import fr.umlv.cmis.listview.CmisObjectListView;
import fr.umlv.utils.ExceptionUtils;
import fr.umlv.utils.InfiniteProgressPanel;

// TODO: Auto-generated Javadoc
/**
 * The Class InviteUsersView.
 */
public class InviteUsersView {
	
	/** The shell list view. */
	private final CmisObjectListView shellListView;
	
	/** The browser window. */
	private final BrowserWindow browserWindow;
	
	/** The bundle. */
	private final ResourceBundle bundle = ResourceBundle.getBundle("kiyut.ekspos.BrowserWindow", SessionHandler.getLocale());

	/** The selected cmis obj. */
	private CmisObject selectedCmisObj ;
	
	/** The person permissions. */
	private Map<Person, List<String>> personPermissions;

	/**
	 * Instantiates a new invite users view.
	 *
	 * @param cmisObjListView the cmis obj list view
	 * @param browserWin the browser win
	 */
	public InviteUsersView(CmisObjectListView cmisObjListView, BrowserWindow browserWin) {
		this.shellListView = cmisObjListView;
		this.browserWindow = browserWin;
	}

	/**
	 * Invite delete dialog.
	 *
	 * @return the j dialog
	 */
	public JDialog inviteDeleteDialog() {
		final JDialog mainDialog = new JDialog(browserWindow, true);
		try {
			this.selectedCmisObj = shellListView.getSelectedFiles().get(0);
			this.personPermissions = Permissions.getPermissions(selectedCmisObj);
			final CmisObject selectedCmisObj = shellListView.getSelectedFiles().get(0);
			mainDialog.setTitle(bundle.getString("invite.usersForFile.title")+selectedCmisObj.getName());
			JTabbedPane jtp = new JTabbedPane();
			jtp.add(invite(mainDialog));
			jtp.add(deleteUser());
			mainDialog.add(jtp);
			mainDialog.setSize(740, 480);
			mainDialog.setLocationRelativeTo(browserWindow);
			mainDialog.setVisible(true);
			return mainDialog;
		} catch (CmisBaseException cbe) {
			ExceptionUtils.createCmisJXBaseException(cbe, mainDialog);
		} catch (IllegalArgumentException iae) {
			ErrorInfo info = new ErrorInfo(iae.getMessage(), iae.getMessage(), null, "IllegalArgument", iae, Level.WARNING, null);
			JXErrorPane.showDialog(shellListView, info); 
		} catch (IOException e) {
			ErrorInfo info = new ErrorInfo(bundle.getString("message.notAllowedTitle"), bundle.getString("message.notAllowed"), null, "IOException", e, Level.WARNING, null);
			JXErrorPane.showDialog(shellListView, info); 
		} catch (ParseException e) {
			ErrorInfo info = new ErrorInfo(e.getMessage(), e.getMessage(), null, "ParseException", e, Level.WARNING, null);
			JXErrorPane.showDialog(shellListView, info); 
		}
		return mainDialog;
	}

	/**
	 * Invite.
	 *
	 * @param mainDialog the main dialog
	 * @return the j panel
	 */
	private JPanel invite(final JDialog mainDialog) {
		final JPanel invitePanel = new JPanel();
		if (shellListView.getSelectedFiles()==null) {
			throw new ArrayIndexOutOfBoundsException("Nothing selected !");
		}
		invitePanel.setName(bundle.getString("invite.inviteEditUsers.tabbed"));
		GridBagConstraints gridBagConstraints;
		invitePanel.setLayout(new GridBagLayout());

		//JTextField rechGroupesTextField = new JTextField();
		//JButton rechGroupes = new JButton();
		final JTextField rechUtilisTextField = new JTextField();
		final JButton rechUtilisateurs = new JButton();

		JScrollPane jScrollPaneListeUtilisateurs = new JScrollPane();
		final JList jListUtilisateurs = new JList();
		jListUtilisateurs.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		JScrollPane jScrollPaneRoles = new JScrollPane();
		final JList jListRoles = new JList();
		jListRoles.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		JScrollPane jScrollPaneInviter = new JScrollPane();
		final JList jListInviter = new JList();

		JButton utilisateursAToutAjouter = new JButton();
		JButton utilisateursAAjouter = new JButton();
		JButton utilisateursARetirer = new JButton();

		JLabel roles = new JLabel();

		JLabel utilisateurs = new JLabel();
		JLabel utilisateursAInviter = new JLabel();

		final JCheckBox mailConfirmation = new JCheckBox();
		JButton inviterUtilisateurs = new JButton();

		final DefaultListModel listUsersModel = new DefaultListModel();

		final ListModel listRolesModel = new AbstractListModel() {
			private static final long serialVersionUID = 1L;
			List<String> listRoles = 
				Permissions.getDisplayNamesRoles();;

				public int getSize() { return listRoles.size(); }
				public Object getElementAt(int i) { return listRoles.get(i); }
		};

		final SortedListModel listInviterModel = new SortedListModel();


		ActionListener rechUserActionListener = new ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				final InfiniteProgressPanel progress = new InfiniteProgressPanel();
				mainDialog.setGlassPane(progress);
				progress.setSize(mainDialog.getWidth(), mainDialog.getHeight());

				progress.start();

				try {
					String utilisateur = rechUtilisTextField.getText();
					UsersUtils test = new UsersUtils(utilisateur);
					List<Person> users = test.getPersons();
					Object[] argg = {utilisateur};
					if (users.isEmpty()) {
						progress.interrupt();
						JOptionPane.showMessageDialog(invitePanel, MessageFormat.format(bundle.getString("message.userNotExists.text"), argg),bundle.getString("message.userNotExists.title"), JOptionPane.ERROR_MESSAGE);
						return;
					}

					listUsersModel.clear();
					for (Person username : users) {
						List<String> roles = new ArrayList<String>();
						for(String role : Permissions.getPermissionsForUser(personPermissions, username.getUserName())){
							roles.add(new String(role));
						}
						listUsersModel.addElement(new User(username, roles));
					}
				} catch (CmisBaseException cbe) {
					progress.interrupt();
					ExceptionUtils.createCmisJXBaseException(cbe, mainDialog);
				} catch (IllegalArgumentException iae) {
					progress.interrupt();
					ErrorInfo info = new ErrorInfo(iae.getMessage(), iae.getMessage(), null, "IllegalArgument", iae, Level.WARNING, null);
					JXErrorPane.showDialog(invitePanel, info); 
				} catch (IOException e) {
					progress.interrupt();
					ErrorInfo info = new ErrorInfo(e.getMessage(), e.getMessage(), null, "IOException", e, Level.WARNING, null);
					JXErrorPane.showDialog(invitePanel, info); 
				} catch (ParseException e) {
					progress.interrupt();
					ErrorInfo info = new ErrorInfo(e.getMessage(), e.getMessage(), null, "ParseException", e, Level.WARNING, null);
					JXErrorPane.showDialog(invitePanel, info); 
				} finally {
					progress.interrupt();
				}
			}
		};
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.ipadx = 256;
		gridBagConstraints.insets = new Insets(10, 6, 0, 0);
		invitePanel.add(rechUtilisTextField, gridBagConstraints);
		rechUtilisTextField.addActionListener(rechUserActionListener);

		rechUtilisateurs.setText(bundle.getString("invite.findusers.label"));
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 2;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.gridwidth = 4;
		gridBagConstraints.gridheight = 2;
		gridBagConstraints.insets = new Insets(5, 9, 0, 0);
		invitePanel.add(rechUtilisateurs, gridBagConstraints);
		rechUtilisateurs.addActionListener(rechUserActionListener);

		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.gridwidth = 2;
		gridBagConstraints.ipadx = 256;
		gridBagConstraints.insets = new Insets(10, 6, 0, 0);
		//invitePanel.add(rechGroupesTextField, gridBagConstraints);
		//rechGroupes.setText(bundle.getString("invite.findgroups.label"));
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 2;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.gridwidth = 4;
		gridBagConstraints.gridheight = 2;
		gridBagConstraints.ipadx = 14;
		gridBagConstraints.insets = new Insets(5, 9, 0, 0);

		utilisateurs.setText(bundle.getString("invite.users.label"));
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 4;
		gridBagConstraints.insets = new Insets(11, 6, 0, 0);
		invitePanel.add(utilisateurs, gridBagConstraints);

		jListUtilisateurs.setModel(listUsersModel);
		jScrollPaneListeUtilisateurs.setViewportView(jListUtilisateurs);

		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 5;
		gridBagConstraints.gridwidth = 3;
		gridBagConstraints.gridheight = 5;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 192;
		gridBagConstraints.insets = new Insets(6, 6, 0, 0);
		invitePanel.add(jScrollPaneListeUtilisateurs, gridBagConstraints);

		utilisateursAAjouter.setText(">");
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.anchor = GridBagConstraints.BASELINE;
		gridBagConstraints.gridx = 5;
		gridBagConstraints.gridy = 5;
		invitePanel.add(utilisateursAAjouter, gridBagConstraints);


		utilisateursAAjouter.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Object[] listUsers = jListUtilisateurs.getSelectedValues();
				Object[] listRoles = jListRoles.getSelectedValues();
				if ((listUsers!=null)&&(listRoles!=null)) {
					if (listUsers.length<=0) {
						JOptionPane.showMessageDialog(null, bundle.getString("message.userNotSelected.text"),bundle.getString("message.userNotSelected.title"), JOptionPane.ERROR_MESSAGE);
						return;
					}
					if (listRoles.length<=0) {
						JOptionPane.showMessageDialog(null, bundle.getString("message.pleaseSelectRole.text"),bundle.getString("message.pleaseSelectRole.text"), JOptionPane.ERROR_MESSAGE);
						return;
					}
					for (int i = 0; i < listUsers.length; i++) {
						User user = (User)listUsers[i];
						user.clearPermissions();
						for (int j = 0; j < listRoles.length; j++) {
							user.addPermission((String)listRoles[j]);
						}
						listInviterModel.add(user);
					}
				}
			}
		});
		utilisateursAToutAjouter.setText(">>");
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 5;
		gridBagConstraints.gridy = 7;
		gridBagConstraints.anchor = GridBagConstraints.BASELINE;
		invitePanel.add(utilisateursAToutAjouter, gridBagConstraints);

		utilisateursAToutAjouter.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				int total = listUsersModel.getSize();
				Object[] listRoles = jListRoles.getSelectedValues();
				if ((listRoles!=null)) {
					if (listRoles.length<=0) {
						JOptionPane.showMessageDialog(null, bundle.getString("message.pleaseSelectRole.text"),bundle.getString("message.pleaseSelectRole.text"), JOptionPane.ERROR_MESSAGE);
						return;
					}
					for(int k=0; k<total; k++) {
						User user = (User) listUsersModel.get(k);
						user.clearPermissions();
						for (int j = 0; j < listRoles.length; j++) {
							user.addPermission((String)listRoles[j]);
						}
						listInviterModel.add(user);
					}
				}
			}
		});

		utilisateursARetirer.setText("<"); 
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 5;
		gridBagConstraints.gridy = 6;
		gridBagConstraints.anchor = GridBagConstraints.BASELINE;
		invitePanel.add(utilisateursARetirer, gridBagConstraints);
		utilisateursARetirer.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (listInviterModel.getSize()>0) {
					Object[] objs = jListInviter.getSelectedValues();
					for (int i = 0; i < objs.length; i++) {
						User u = (User)objs[i];
						// Restore user permissions
						u.clearPermissions();
						for(String s:Permissions.getPermissionsForUser(personPermissions, u.getPerson().getUserName())) 
							u.addPermission(s);
						listInviterModel.removeElement(u);
					}
				}
			}
		});

		roles.setText(bundle.getString("invite.roles.label")); 
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.anchor = GridBagConstraints.WEST;
		gridBagConstraints.gridx = 5;
		gridBagConstraints.gridy = 8;
		gridBagConstraints.insets = new java.awt.Insets(11, 18, 0, 0);
		invitePanel.add(roles, gridBagConstraints);

		jListRoles.setModel(listRolesModel);
		jScrollPaneRoles.setViewportView(jListRoles);

		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 5;
		gridBagConstraints.gridy = 9;
		gridBagConstraints.gridwidth = 10;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 79;
		gridBagConstraints.ipady = 104;
		gridBagConstraints.insets = new Insets(6, 18, 0, 0);
		invitePanel.add(jScrollPaneRoles, gridBagConstraints);

		utilisateursAInviter.setText(bundle.getString("invite.usersToInvite.label")); 
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 15;
		gridBagConstraints.gridy = 4;
		gridBagConstraints.insets = new Insets(11, 18, 0, 0);
		invitePanel.add(utilisateursAInviter, gridBagConstraints);

		jListInviter.setModel(listInviterModel);
		jScrollPaneInviter.setViewportView(jListInviter);


		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 15;
		gridBagConstraints.gridy = 5;
		gridBagConstraints.gridwidth = 18;
		gridBagConstraints.gridheight = 5;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 192;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new Insets(6, 18, 0, 6);
		invitePanel.add(jScrollPaneInviter, gridBagConstraints);

		mailConfirmation.setText(bundle.getString("invite.usersMailConfirmation.label"));
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 5;
		gridBagConstraints.gridy = 10;
		gridBagConstraints.insets = new Insets(7, 7, 0, 0);
		invitePanel.add(mailConfirmation, gridBagConstraints);

		inviterUtilisateurs.setText(bundle.getString("invite.inviteUsers.label"));
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 11;
		gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER;
		gridBagConstraints.ipadx = 433;
		gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints.insets = new Insets(7, 10, 23, 7);
		invitePanel.add(inviterUtilisateurs, gridBagConstraints);


		inviterUtilisateurs.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				/*HashMap<Person, List<String>> newPermissions = new HashMap<Person, List<String>>();
				for (int i = 0; i < jListInviter.getModel().getSize(); i++) {
					User u = (User) jListInviter.getModel().getElementAt(i);
					newPermissions.put(u.getPerson(), u.getPermissions());
				}
				try {
					Permissions.updatePermissions(selectedCmisObj, personPermissions, newPermissions);
				} catch (CmisBaseException cbe) {
					ExceptionUtils.createCmisJXBaseException(cbe, mainDialog);
				} catch (IOException e1) {
					ExceptionUtils.createJXErrorIOException(e1, mainDialog);
				} catch (ParseException e1) {
					ExceptionUtils.createJXErrorException(e1, mainDialog);
				}*/

				
				//SwingUtilities.invokeLater(new Runnable() {
					
					//@Override
					//public void run() {
						invitePanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
						//final InfiniteProgressPanel glassPane = new InfiniteProgressPanel();
						//glassPane.setSize(800, 800);
						
						//mainDialog.setGlassPane(glassPane);
						//glassPane.start();
						HashMap<Person, List<String>> newPermissions = new HashMap<Person, List<String>>();
						for (int i = 0; i < jListInviter.getModel().getSize(); i++) {
							User u = (User) jListInviter.getModel().getElementAt(i);
							newPermissions.put(u.getPerson(), u.getPermissions());
						}
						try {
							if (newPermissions.isEmpty()) {
								//glassPane.interrupt();
								invitePanel.setCursor(Cursor.getDefaultCursor());
								JOptionPane.showMessageDialog(invitePanel, bundle.getString("message.userNotSelected.text"),bundle.getString("message.userNotSelected.title"), JOptionPane.ERROR_MESSAGE);
								return;
							} else {
								Permissions.updatePermissions(selectedCmisObj, personPermissions, newPermissions);
								if(mailConfirmation.isSelected()){
									SendMailSSL mail = new SendMailSSL(newPermissions, selectedCmisObj);
									mail.sendMailInvite();
								}
								mainDialog.dispose();
							}
						} catch (IOException e1) {
							//glassPane.interrupt();
							invitePanel.setCursor(Cursor.getDefaultCursor());
							ExceptionUtils.createJXErrorIOException(e1, mainDialog);
						} catch (ParseException e2) {
							//glassPane.interrupt();
							invitePanel.setCursor(Cursor.getDefaultCursor());
							ExceptionUtils.createJXErrorException(e2, mainDialog);
						} finally {
							//glassPane.interrupt();
							invitePanel.setCursor(Cursor.getDefaultCursor());
						}
					}
				//});
			//}
		});

		return invitePanel;
	}

	/**
	 * Delete user.
	 *
	 * @return the j panel
	 */
	private JPanel deleteUser() {
		GridBagConstraints gridBagConstraints;
		final JPanel deletePanel = new JPanel();
		deletePanel.setLayout(new GridBagLayout());
		deletePanel.setName(bundle.getString("invite.deleteUsers.tabbed"));
		JButton supprimerUtilisateurs = new JButton();
		JScrollPane jScrollPaneListeUtilisateurs = new JScrollPane();

		final SortedListModel listUsersModel = new SortedListModel();


		for (Map.Entry<Person, List<String>> e : personPermissions.entrySet()) {
			Person p = e.getKey();
			List<String> roles = new ArrayList<String>();
			for(String role : e.getValue()){
				roles.add(role);
			}
			listUsersModel.add(new User(p, roles));
		}

		JLabel utilisateurs = new JLabel();
		utilisateurs.setText("Utilisateurs :");
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 0.0;
		gridBagConstraints.anchor = GridBagConstraints.WEST;
		gridBagConstraints.insets = new Insets(6, 6, 0, 0);
		deletePanel.add(utilisateurs, gridBagConstraints);

		final JList jListUtilisateurs = new JList();
		jListUtilisateurs.setModel(listUsersModel);
		jScrollPaneListeUtilisateurs.setViewportView(jListUtilisateurs);

		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.weightx = 0.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 192;
		gridBagConstraints.insets = new Insets(6, 6, 6, 6);
		deletePanel.add(jScrollPaneListeUtilisateurs, gridBagConstraints);

		supprimerUtilisateurs.setText(bundle.getString("invite.deleteUsers.button"));
		supprimerUtilisateurs.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				Object[] usersToDelete = jListUtilisateurs.getSelectedValues();
				for (int i = 0; i < usersToDelete.length; i++) {
					User user = (User)usersToDelete[i];
					try {
						Permissions.deletePermissions(selectedCmisObj, user.getPerson().getUserName());
						listUsersModel.removeElement(user);
					} catch (CmisBaseException cbe) {
						ExceptionUtils.createCmisJXBaseException(cbe, deletePanel);
					}catch (IOException e1) {
						ExceptionUtils.createJXErrorIOException(e1, deletePanel);
					} catch (ParseException e1) {
						ExceptionUtils.createJXErrorException(e1, deletePanel);
					}
				}
			}
		});
		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER;
		gridBagConstraints.gridheight = GridBagConstraints.REMAINDER;
		gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints.weightx = 0.0;
		gridBagConstraints.weighty = 0.0;
		gridBagConstraints.insets = new Insets(7, 10, 23, 7);
		deletePanel.add(supprimerUtilisateurs, gridBagConstraints);
		return deletePanel;
	}
}
class SortedListModel extends AbstractListModel {
	private static final long serialVersionUID = 1L;
	private final HashSet<User> hashSet;

	public SortedListModel() {
		hashSet = new HashSet<User>();
	}

	public int getSize() {
		return hashSet.size();
	}

	public Object getElementAt(int index) {
		return hashSet.toArray()[index];
	}

	public void add(User element) {
		if (hashSet.contains(element)) {
			hashSet.remove(element);
		}
		if (hashSet.add(element)) {
			fireContentsChanged(this, 0, getSize());
		}
	}

	public void addAll(User elements[]) {
		Collection<User> c = Arrays.asList(elements);
		hashSet.addAll(c);
		fireContentsChanged(this, 0, getSize());
	}

	public void clear() {
		hashSet.clear();
		fireContentsChanged(this, 0, getSize());
	}

	public boolean contains(Object element) {
		return hashSet.contains(element);
	}

	public Iterator<User> iterator() {
		return hashSet.iterator();
	}

	public boolean removeElement(User element) {
		boolean removed = hashSet.remove(element);
		if (removed) {
			fireContentsChanged(this, 0, getSize());
		}
		return removed;
	}
}
